// 导入 threejs
import * as THREE from 'three'
// 导入轨道控制器
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
// 导入lil.gui
import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.js'

// 创建场景
const scene= new THREE.Scene()

// 创建相机
const camera = new THREE.PerspectiveCamera(
  45,  // 视角
  window.innerWidth / window.innerHeight,
  0.1,  // 近平面
  1000   // 远平面
)

// 创建渲染器
const renderer = new THREE.WebGLRenderer()
renderer.setSize(window.innerWidth, window.innerHeight)   // 整屏渲染，canvas为基础

// 将画布添加到页面标签里
document.body.appendChild(renderer.domElement)


// // 创建几何体，立方体
// const geometry = new THREE.BoxGeometry(1, 1, 1)
// // 创建材质
// const material = new THREE.MeshBasicMaterial({color: 0x00ff00})  // 设置材质颜色为绿色
// // 创建网格，展现具体的物体了，绿色的几何体
// const cube = new THREE.Mesh(geometry, material)
// material.wireframe = true
// // 将网格添加到场景中
// scene.add(cube)

/*
threejs 中都是以三角形建立面的， 以点构建三角形, 三个点表示一个三角形
  一个点的x,y,z的坐标是以三个浮点型数据表示的 , 这个点被称为顶点
*/
// 创建基础几何体
const geometry = new THREE.BufferGeometry(); 
// 创建顶点数据, 构建浮点型数组， 每3个一组，顶点是有顺序的，逆时针为正面
// const vertices = new Float32Array([
//   -1.0, -1.0, 0.0, 
//   1.0, -1.0, 0.0,
//   1.0, 1.0, 0.0,
//   // 设置第二个三角形，形成一个正方形
//   1.0, 1.0, 0.0,
//   -1.0, 1.0, 0.0,
//   -1.0, -1.0, 0.0
// ])
// // 创建顶点属性
// geometry.setAttribute("position", new THREE.BufferAttribute(vertices, 3)) // 设置顶点属性，以 数组中的每三个为一组数据

// 共用顶点
// 使用索引绘制
const vertices = new Float32Array([
  -1.0, -1.0, 0.0, 
  1.0, -1.0, 0.0,
  1.0, 1.0, 0.0,
  -1.0, 1.0, 0.0
])
// 创建顶点属性
geometry.setAttribute("position", new THREE.BufferAttribute(vertices, 3))  // 以 数组中的每三个为一组数据
// 创建索引
const indices = new Uint16Array([0, 1, 2,
                                  2, 3, 0])         // 相当于共用两个顶点， 第0组数据，第2组数据
// 创建索引属性
geometry.setIndex(new THREE.BufferAttribute(indices, 1))

const material = new THREE.MeshBasicMaterial({
  color: 0x00ff00,
  // side: THREE.DoubleSide,      // 设置两面都能看到(非线框状态下)
  wireframe: true              // 设置是否是线框，先隐藏,看每组数组的顺序看能在正面还是背面能看到
})
const plane = new THREE.Mesh(geometry, material)   // 创建平面

scene.add(plane)


// 添加世界坐标辅助器，x,y,z轴的辅助线
const axesHelper = new THREE.AxesHelper(5)   // 并设置线段的长度为5
// 添加到场景当中
scene.add(axesHelper)

// 设置相机位置
// camera.position.z = 5   // 设置在哪个轴， x, y, z 这里设置z轴
// camera.lookAt(0, 0, 0)    // 设置相机看向什么位置，看向原点位置

// 为了看到z轴的线，调整相机位置
camera.position.z = 5   
camera.position.x = 3
camera.position.y = 2
camera.lookAt(0, 0, 0)  

// 添加轨道控制器， 先在上面导入
const controls = new OrbitControls(camera, renderer.domElement)   // renderer.domElement这个表示监听的元素是 canvas 元素， 渲染的标签
// const controls = new OrbitControls(camera, document.body)   // 监听body
// 设置带阻尼的惯性，阻尼感
controls.enableDamping = true         // 开启
// 设置阻尼系数
// controls.dampingFactor = 0.01          // 越小阻尼感越大
controls.dampingFactor = 0.5
// controls.autoRotate = true         // 自转，自动绕着目标旋转， 开启这个必须要使用 controls方法

// 做一个渲染函数， 不断渲染
function animate() {
  controls.update()    // 渲染的时候也要每次更新控制器
  requestAnimationFrame(animate)       // 相当于定时器，不断调用，一直渲染
  // 旋转功能
  // cube.rotation.x += 0.01
  // cube.rotation.y += 0.01
  // 渲染
  renderer.render(scene, camera)
}
animate()

// 监听窗口变化
window.addEventListener("resize", () => {
  // 重置渲染器宽高比
  renderer.setSize(window.innerWidth, window.innerHeight)
  // 重置相机宽高比
  camera.aspect = window.innerWidth / window.innerHeight
  // 更新相机投影矩阵 ， 一定要加
  camera.updateProjectionMatrix()
})


let debugEvent = {
  // 全屏函数
  Fullscreen: function() {
    renderer.domElement.requestFullscreen()
  }
}

// 创建GUI
const gui = new GUI()
// gui.add(debugEvent, "Fullscreen")        // 会在界面上自动创建调试的按钮
gui.add(debugEvent, "Fullscreen").name("全屏")  // 设置名字

    